﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Basmus.Patterns
{
	public class LazyLoading<TKey, TValue>
	{
		private Dictionary<TKey, TValue> map = new Dictionary<TKey, TValue>();
		public Func<TKey, TValue> LazyLoadingFunc { get; set; }
		public TValue this[TKey key]
		{
			get
			{
				if (map.ContainsKey(key))
				{
					return map[key];
				}
				else
				{
					TValue value = LazyLoadingFunc(key);
					map.Add(key, value);
					return value;
				}
			}
		}
		public void Release(TKey key)
		{
			map.Remove(key);
		}
		public IEnumerable<TKey> Keys
		{
			get { return map.Keys; }
		}
	}
	public static class LazyLoading
	{
		public static LazyLoading<TKey, TValue> ToLazyLoading<TKey, TValue>(this Func<TKey, TValue> func)
		{
			return new LazyLoading<TKey, TValue> { LazyLoadingFunc = func };
		}
		public static TValue Cache<TKey, TValue>(this Func<TKey, TValue> func, TKey key)
		{
			LazyLoading<TKey, TValue> ll = SingletonProvider<LazyLoading<TKey, TValue>>.Instance;
			if (ll.LazyLoadingFunc == null || ll.LazyLoadingFunc == func)
			{
				ll.LazyLoadingFunc = func;
			}
			else
			{
				throw new Exception();
			}
			return ll[key];
		}
	}
}
